<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>es5 构造函数的类方法</title>
  <!-- 
  在 JavaScript ES5 中，构造函数是一种创建对象的常用方式。构造函数可以包含类方法（即原型方法），这些方法可以被通过该构造函数创建的所有实例共享。
  1. 构造函数的基本概念
  - 构造函数：通常以大写字母开头的函数，用于创建对象的实例。
  - 实例属性：在构造函数内部使用  `this`  关键字定义的属性，属于每个实例。
  - 原型方法：在构造函数的  `prototype`  属性上定义的方法，可以被所有实例共享。

  2. 创建构造函数
  以下是创建构造函数的基本步骤：

   2.1 定义构造函数
  使用  `function`  关键字定义构造函数，并在其中初始化实例属性。
  function Person(name, age) {
      this.name = name; // 实例属性
      this.age = age;   // 实例属性
  }
   2.2 定义类方法
  在构造函数的  `prototype`  属性上定义方法，这些方法将成为所有实例共享的方法。
  Person.prototype.sayHello = function() {
      console.log("Hello, my name is " + this.name);
  };

  Person.prototype.sayAge = function() {
      console.log("I am " + this.age + " years old.");
  };
  3. 创建实例
  通过构造函数创建实例，并调用类方法。
  var alice = new Person("Alice", 30);
  alice.sayHello(); // 输出: Hello, my name is Alice
  alice.sayAge();   // 输出: I am 30 years old.
  4. 优缺点
  - 优点：
    - 内存效率：通过原型方法，所有实例共享同一份方法，节省内存。
    - 可扩展性：可以在构造函数的原型上随时添加新方法，所有实例都可以访问。

  - 缺点：
    - 无法访问私有属性：原型方法无法直接访问实例的私有属性，必须通过  `this`  关键字来访问。
    - 方法的重写：如果在实例上定义与原型方法同名的方法，实例方法会遮蔽原型方法。

  总结
  在 ES5 中，构造函数是创建对象的主要方式，通过在构造函数的  `prototype`  上定义类方法，可以实现方法的共享和代码的复用。理解构造函数和类方法的概念对于掌握 JavaScript 的面向对象编程非常重要。这种方式不仅提高了内存使用效率，还增强了代码的可维护性和可扩展性。
  -->
</head>
<body>

  <script>
    // var obj = {
    //   friend: {
    //     play: function() {
    //       console.log("play~")
    //     }
    //   }
    // }
    // obj.play()

    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    Person.totalCounter = "70亿"
    Person.prototype.sayHello = function() {
      console.log("Hello, my name is " + this.name);
    };
    Person.prototype.sayAge = function() {
      console.log("I am " + this.age + " years old.");
    }

    const names = ["Alice", "Bob", "Charlie"];
    Person.randomName = function() {
      const randomName = names[Math.floor(Math.random() * names.length)];
      return new Person(randomName, Math.floor(Math.random() * 100));
    }

    // 创建实例对象
    const person1 = new Person("Alice", 25);
    person1.sayHello();
    
    // 没有实例对象的情况下, 能不能调用函数? 不可以调用
    var p = Person.randomName()
    console.log(p)
    
  </script>
  
</body>
</html>